<?php
/**
 * 插件 - Thrift
 * // 默认采用二进制的数据压缩机制
 *
 * @version $Id: Thrift.php 155 2013-11-19 06:32:45Z linsir123 $
 * @package Helper
 */
class HelperThrift
{
	/**
	 * 控制器类名前缀
	 */
	const PRE_ACTION = "Action";

	/**
	 * Thrift包路径
	 *
	 * @var string
	 */
	private $_thriftPath;

	/**
	 * 初始化
	 *
	 * @param string $thriftPath Thrift包路径
	 */
	public function init($thriftPath = null)
	{
		///
		if (empty($thriftPath))
			$thriftPath = $GLOBALS['THRIFT_ROOT'];

		$tmp = substr($thriftPath, - 1);
		if ($tmp == "\\" || $tmp == "/")
			$thriftPath = substr($thriftPath, 0, - 1);

		if (! empty($thriftPath) && file_exists($thriftPath))
			$this->_thriftPath = $thriftPath;

		///
		require_once $this->_thriftPath . '/Thrift.php';
		require_once $this->_thriftPath . '/protocol/TBinaryProtocol.php';
	}

	/**
	 * 执行方法
	 *
	 * @param string $method 方法名
	 * @param array $args 参数
	 * @param string $controller 控制器名，可用于调用其它服务中的方法
	 *
	 * @return mixed
	 * @throws Exception
	 */
	public function handleAction($method, $args = null, $controller = null)
	{
		$method = ucfirst($method);
		$className = self::PRE_ACTION . $method;
		if (empty($controller))
			$controller = App::$I->getDispatcher()->controller;

		$filePath = sprintf("%sController/%s/%s.php",
			APP_DIR,
			$controller,
			$method
		);

		///
		if (! file_exists($filePath))
			throw new Exception("[Thrift - Action] file miss.");

		///
		require($filePath);
		if (! class_exists($className))
			throw new Exception("[Thrift - Action] class miss.");

		///
		$o = App::$I->singleton($className);
		if (! method_exists($o, 'handler'))
			throw new Exception("[Thrift - Action] method miss.");

		///
		return call_user_func_array(array($o, 'handler'), $args);
	}

	/**
	 * 启动一个thrift服务
	 *
	 * @param string $handler
	 * @param string $processorClass
	 */
	public function service($handler, $processorClass)
	{
		///
		require_once $this->_thriftPath . '/transport/TPhpStream.php';

		///
		$php = new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W);
		$transport = new TBufferedTransport($php);
		$transport->open();

		///
		$processor = App::$I->singleton($processorClass, array($handler));
		$protocol = new TBinaryProtocol($transport, true, true);
		$processor->process($protocol, $protocol);

		///
		$transport->close();
	}

	/**
	 * 构造一个thrift客户端协议
	 *
	 * @param string  $serverUrl
	 *
	 * @return mixed
	 */
	public function getClientProtocol($serverUrl)
	{
		///
		require_once $this->_thriftPath . '/transport/THttpClient.php';

		///
		$data = parse_url($serverUrl);
		$host = isset($data['host']) ? trim($data['host']) : '';
		$path = isset($data['path']) ? trim($data['path']) : '';
		$port = isset($data['port']) ? intval($data['port']) : 80;

		///
		$http = new THttpClient($host, $port, $path);
		$transport = new TBufferedTransport($http, 1024, 1024);
		$protocol = new TBinaryProtocol($transport);
		$transport->open();

		///
		return $protocol;
	}
}
